package com.dattplace.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.dattplace.dao.IMongodbDAO;
import com.dattplace.dao.IShareDao;
import com.dattplace.model.FeedBack;
import com.dattplace.model.Paginate;
import com.dattplace.model.PlatformShare;
import com.dattplace.model.Praise;
import com.dattplace.model.ReleaseVersion;
import com.dattplace.model.ShareComment;
import com.dattplace.model.ShareTimes;
import com.dattplace.model.User;
import com.dattplace.mongoSupport.QueryParamCreator;
import com.dattplace.util.DateUtil;
import com.dattplace.util.StringUtil;


@Persistent
@Service("shareDao")
public class ShareDao implements IShareDao {

	@Autowired
	private IMongodbDAO dao;

	@Override
	public void deleteShare(String shareId) {
		dao.deletePOList(ShareTimes.class, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public ShareTimes querShareById(String shareId) {
		return dao.getPO(ShareTimes.class, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public synchronized void updatePraiseCount(String shareId, int type) {
		dao.updateInc(ShareTimes.class, "praiseCount", type, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public void updatePraiseList(Praise p,String shareId) {
		dao.saveArray(ShareTimes.class, "praiseListt", p, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public void saveShare(ShareTimes st) {
		dao.saveOrUpdatePO(st);
	}

	@Override
	public void comment(ShareComment sc) {
		dao.saveOrUpdatePO(sc);
	}

	@Override
	public List<ShareComment> queryCommonList(String shareId) {
		return dao.getPOList(ShareComment.class, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public List<ShareTimes> shareList(int pageNo, int pageSize, String keyWord,int shareType,int queryType) {
		
		List<Order> orders = new ArrayList<Order>();
		
		List<Criteria> condList = new ArrayList<Criteria>();
		
		if(shareType>0){
			condList.add(QueryParamCreator.eq("shareType", shareType));
		}
		
		if(!StringUtil.isEmptyString(keyWord)){
			condList.add(QueryParamCreator.like("content", keyWord));
		}
		
		// post
		if(queryType==1){
			
			
			Order publishType = new Order(Direction.DESC, "publishType");
			Order praiseCount = new Order(Direction.DESC, "praiseCount");
			Order commentCount = new Order(Direction.DESC, "commentCount");
			Order shareTime = new Order(Direction.DESC, "shareTime");
			orders.add(publishType);
			orders.add(praiseCount);
			orders.add(commentCount);
			orders.add(shareTime);
		}
		// latest
		if(queryType==2){
			
			Order publishType = new Order(Direction.DESC, "publishType");
			Order shareTime = new Order(Direction.DESC, "shareTime");
			orders.add(publishType);
			orders.add(shareTime);
			Date date =DateUtil.strToDate(DateUtil.dataToString(new Date(), "yyyy-MM-dd")+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
			condList.add(QueryParamCreator.gt("shareTime", date));
		}
		
		if(queryType==0){
			Order shareTime = new Order(Direction.DESC, "shareTime");
			orders.add(shareTime);
		}
		condList.add(QueryParamCreator.isNotEmpty("shareId"));
		return dao.getPOList(ShareTimes.class, new Paginate(pageNo, pageSize), orders, (Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public long queryShareCount(String userId) {
		return dao.getRowCount(ShareTimes.class, QueryParamCreator.eq("userId", userId));
	}

	@Override
	public long queryAllUserCount(String content, int shareType, String nickName, String shareStartDate, String shareEndDate) {
		List<Criteria> condList = new ArrayList<Criteria>();
		if(shareType>0){
			condList.add(QueryParamCreator.eq("shareType", shareType));
		}
		
		if(!StringUtil.isEmptyString(content)){
			condList.add(QueryParamCreator.like("content", content));
		}
		
		if(!StringUtil.isEmptyString(nickName)){
			
			List<String> ids =new ArrayList<>();
			List<User> uList =dao.getPOList(User.class, QueryParamCreator.like("nickName", nickName));
			if(!CollectionUtils.isEmpty(uList)){
				for(User u:uList){
					if(!ids.contains(u.getUserId())){
						ids.add(u.getUserId());
					}
				}
			}
			condList.add(QueryParamCreator.in("userId", ids));
		}
		
		if(!StringUtil.isEmptyString(shareStartDate) && !StringUtil.isEmptyString(shareEndDate)){
			condList.add(QueryParamCreator.between("shareTime", DateUtil.strToDate(shareStartDate+" 00:00:00", "yyyy-MM-dd HH:mm:ss"), DateUtil.strToDate(shareEndDate+" 23:59:59", "yyyy-MM-dd HH:mm:ss")));
		}
		else if(!StringUtil.isEmptyString(shareStartDate)){
			condList.add(QueryParamCreator.ge("shareTime", DateUtil.strToDate(shareStartDate+" 00:00:00", "yyyy-MM-dd HH:mm:ss")));
		}else if(!StringUtil.isEmptyString(shareEndDate)){
			condList.add(QueryParamCreator.le("shareTime", DateUtil.strToDate(shareEndDate+" 23:59:59", "yyyy-MM-dd HH:mm:ss")));
		}
		return dao.getRowCount(ShareTimes.class,(Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public void updateShare(Map<String, Object> property, String shareId) {
		dao.saveOrUpdateDocument(ShareTimes.class, property, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public Praise queryPraise(String shareId, String userId) {
		return dao.getPO(Praise.class, QueryParamCreator.eq("shareId", shareId),QueryParamCreator.eq("userId", userId));
	}

	@Override
	public void savePraise(Praise ps) {
		dao.saveOrUpdatePO(ps);
	}

	@Override
	public void deletePraise(String shareId, String userId) {
		dao.deletePOList(Praise.class, QueryParamCreator.eq("shareId", shareId),QueryParamCreator.eq("userId", userId));
	}

	@Override
	public void deleteComment(String shareId, String commentId) {
		dao.deletePOList(ShareComment.class, QueryParamCreator.eq("shareId", shareId),QueryParamCreator.eq("commentId", commentId));
	}

	@Override
	public void updateCommentCount(String shareId, int type) {
		dao.updateInc(ShareTimes.class, "commentCount", type, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public List<ShareTimes> shareList(int pageNo, int pageSize, int queryType) {
		return null;
	}

	@Override
	public List<ShareTimes> shareList(int pageNo, int pageSize, String userId) {
		
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "shareTime");
		orders.add(order);
		return dao.getPOList(ShareTimes.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.eq("userId", userId));
	}

	@Override
	public List<ShareComment> queryCommonListByUserId(String userId) {
		return dao.getPOList(ShareComment.class, QueryParamCreator.eq("commentUserId", userId));
	}

	@Override
	public List<ShareTimes> shareList(int pageNo, int pageSize, List<String> shareIds) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "shareTime");
		orders.add(order);
		return dao.getPOList(ShareTimes.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.in("shareId", shareIds));
	}

	@Override
	public void feedback(FeedBack map) {
		dao.saveOrUpdatePO(map);
	}

	@Override
	public void platformShare(PlatformShare map) {
		dao.saveOrUpdatePO(map);
	}

	@Override
	public synchronized void updateShareCount(String shareId, int type) {
		dao.updateInc(ShareTimes.class, "shareCount", type, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public ReleaseVersion autoUpdate() {
		
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "releaseDate");
		orders.add(order);
		List<ReleaseVersion> list = dao.getPOList(ReleaseVersion.class, null, orders, QueryParamCreator.isNotEmpty("appVersion"));
		if(CollectionUtils.isEmpty(list)){
			return null;
		}
		return list.get(0);
	}

	@Override
	public List<ShareTimes> queryShareList(int pageNo, int pageSize, String content, int shareType, String nickName,
			String shareStartDate, String shareEndDate) {
		
		List<Order> orders = new ArrayList<Order>();
		
		List<Criteria> condList = new ArrayList<Criteria>();
		
		Order shareTime = new Order(Direction.DESC, "shareTime");
		orders.add(shareTime);
		if(shareType>0){
			condList.add(QueryParamCreator.eq("shareType", shareType));
		}
		
		if(!StringUtil.isEmptyString(content)){
			condList.add(QueryParamCreator.like("content", content));
		}
		
		if(!StringUtil.isEmptyString(nickName)){
			
			List<String> ids =new ArrayList<>();
			List<User> uList =dao.getPOList(User.class, QueryParamCreator.like("nickName", nickName));
			if(!CollectionUtils.isEmpty(uList)){
				for(User u:uList){
					if(!ids.contains(u.getUserId())){
						ids.add(u.getUserId());
					}
				}
			}
			condList.add(QueryParamCreator.in("userId", ids));
		}
		
		if(!StringUtil.isEmptyString(shareStartDate) && !StringUtil.isEmptyString(shareEndDate)){
			condList.add(QueryParamCreator.between("shareTime", DateUtil.strToDate(shareStartDate+" 00:00:00", "yyyy-MM-dd HH:mm:ss"), DateUtil.strToDate(shareEndDate+" 23:59:59", "yyyy-MM-dd HH:mm:ss")));
		}
		else if(!StringUtil.isEmptyString(shareStartDate)){
			condList.add(QueryParamCreator.ge("shareTime", DateUtil.strToDate(shareStartDate+" 00:00:00", "yyyy-MM-dd HH:mm:ss")));
		}else if(!StringUtil.isEmptyString(shareEndDate)){
			condList.add(QueryParamCreator.le("shareTime", DateUtil.strToDate(shareEndDate+" 23:59:59", "yyyy-MM-dd HH:mm:ss")));
		}
		condList.add(QueryParamCreator.isNotEmpty("shareId"));
		return dao.getPOList(ShareTimes.class, new Paginate(pageNo, pageSize), orders, (Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public synchronized void increaseReadCount(String shareId) {
		dao.updateInc(ShareTimes.class, "readCount",1, QueryParamCreator.eq("shareId", shareId));
	}

	@Override
	public synchronized void increaseReadCount(String shareId, int count) {
		dao.updateInc(ShareTimes.class, "readCount",count, QueryParamCreator.eq("shareId", shareId));
	}
}
